package com.easyfun.healthmagicbox.sync;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.easyfun.healthmagicbox.base.DatabaseAccess;
import com.easyfun.healthmagicbox.base.DatabaseAccessImplementation;
import com.easyfun.healthmagicbox.comm.BaseRedoTask;
import com.easyfun.healthmagicbox.comm.HealthThreadPool;
import com.easyfun.healthmagicbox.ormlite.DatabaseHelper;
import com.easyfun.healthmagicbox.util.PersonProfileCache;
import com.easyfun.healthmagicbox.util.SharedPreferencesUtil;

import android.content.Context;
import android.util.Log;

public class SyncManager implements Runnable , DatabaseAccess{
	
	List<String> redoTaskList = new ArrayList<String>();
	private HealthService service;
	private static SyncManager instance = null;
	private boolean canRun =true;
	private static final String TAG = SyncManager.class.getSimpleName();
	private static long SYNCInterval = 90000;
	
	private Object syncObject = new Object();
	public static void initialize(HealthService service )
	{
		instance = new SyncManager(service);	
		//build the redo task list.
		Map<Integer,String> redoMap = SharedPreferencesUtil.getInstance(service).getsRedoTasks();
		instance.redoTaskList = new ArrayList<String>();
		for (Integer redokey:redoMap.keySet())
		{
			BaseRedoTask task = BaseRedoTask.deserialize(redoMap.get(redokey),service,new BasicCommCallback());
			
			if (task != null)
			{
				//---------------------------------
				if (!task.getRedoTaskID().equals(redokey))
				{
					task.setRedoTaskID(redokey);
				}
				//----------------------------------
				instance.redoTaskList.add(task.serialize());
			}else
			{
				SharedPreferencesUtil.getInstance(service).removeRedoTask(redokey);
			}
		}
		instance.updateInterval();
	}
	private void updateInterval()
	{
		String syncInterval = SharedPreferencesUtil.getInstance(service).getSyncInterval();
		if ((syncInterval!=null)&&(syncInterval.length()!=0)
				&&(!syncInterval.equals("null")))
		{
			//protect too often
			long in = Long.valueOf(syncInterval);
			if (in >= 9000)
				SYNCInterval = in;
		}
	}
	public void stop()
	{
		canRun =false;	
		synchronized (syncObject) {
			syncObject.notifyAll();			
		}
	}
	
	public static SyncManager getInstance()
	{
		return instance;		
	}
	
	private SyncManager(HealthService service)
	{
		this.service = service;
	}
	
	void registerFailedTask(String serializedTask)
	{
		redoTaskList.add(serializedTask);
	}

	boolean runawhile(long time)
	{
		long i = time / 500;
		while ((canRun) && (i>0))
		{
			try {
				Thread.sleep(500);
				i--;
			} catch (InterruptedException e) {
				Log.e(TAG,e.toString());
				e.printStackTrace();
				
			}
		}
		return canRun;
	}
	
	@Override
	public void run() {
		while (canRun)
		{				
			updateInterval();
			//if (!runawhile(SYNCInterval))
			
			Log.i(TAG, "redoTaskList.size = " + redoTaskList.size() + "canRun = " + canRun);
			while ((redoTaskList.size()>0)&&(canRun))
			{				
				BasicCommCallback ccb = new BasicCommCallback();
				BaseRedoTask task = BaseRedoTask.deserialize(redoTaskList.get(0),service,ccb);
				if (task == null)
				{
					Log.e(TAG,"get a null task to redo:" + redoTaskList.get(0));
					redoTaskList.remove(0);
					continue;
				}
				//task.setCallBack(ccb);
				//task.setContext(service);
				
				HealthThreadPool.getInstance().execute(task);
				redoTaskList.remove(0);
				
				if (!runawhile(20000))
				{
					break;
				}			
			}
			updateData();
			
			if (!runawhile(SYNCInterval))
			{
				break;
			}
			
		}
	}
	
	void updateData()
	{

		if (PersonProfileCache.getInstance(service).getUsername(service)==null)
		{
			Log.e(TAG ,"username is null, can't update");
			return;
		}
		
			
			int count = SyncHeartBeatSender.getInstance(service, service).sendHeartBeat();
			//service.displayNotificationMessage("收到健康顾问的建议", true);
			
//			if (count>0)	
//			{
//				if (!runawhile(20000))
//				{
//					return;
//				}	
//			}
				
		//for (PersonProfile p : allpeople) {
			//if no pic, send title and name for generating a picture
		//	ProfileImageView pi = new ProfileImageView(this,p.getPersonID(),p.getImageFileName());
			
		//}
		
	}

	
	@Override
	public DatabaseHelper getHelper(Context context) {
		return DatabaseAccessImplementation.getInstance().getHelper(context);
	}
	public void updateImmediately() {
		updateData();
		
	}
	
	
}
